﻿using System;
using System.Linq;
using System.Net;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Practices.Prism.Regions;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Unity;
using DXTools.UI.Core;
using DXTools.UI.Modules.MetadataBrowser.Views;
using DXTools.UI.Core.Events;
using System.Collections.Generic;
using DXTools.UI.Modules.MetadataBrowser.Model;
using DXTools.UI.Modules.MetadataBrowser.DataProviders;
using DXTools.UI.Core.ViewModel;
using DXTools.Core.CrmSdk;
using System.Collections.ObjectModel;

namespace DXTools.UI.Modules.MetadataBrowser.ViewModels
{
    public class EntitiesViewModel : ViewModelBase
    {
        private IDataProvider _dataProvider = null;
        private const string HEADER_INFO = "Entities View";

        #region Properties

        private IOrderedEnumerable<EntityMetadata> _entityList;
        public IOrderedEnumerable<EntityMetadata> EntityList
        {
            get
            {
                return _entityList;
            }
            set
            {
                _entityList = value;
                RaisePropertyChanged("EntityList");
            }
        }

        private IOrderedEnumerable<EntityMetadata> _filteredEntityList;
        public IOrderedEnumerable<EntityMetadata> FilteredEntityList
        {
            get
            {
                return _filteredEntityList;
            }
            set
            {
                _filteredEntityList = value;
                RaisePropertyChanged("FilteredEntityList");
            }
        }

        private String _searchText;
        public String SearchText
        {
            get
            {
                return _searchText;
            }
            set
            {
                _searchText = value;
                RaisePropertyChanged("SearchText");
            }
        }

        public DelegateCommand<object> SearchCommand { get; private set; }

        #endregion

        #region Constructors

         public EntitiesViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer container)
            :base(regionManager,eventAggregator,container)
        {
            this.HeaderInfo = HEADER_INFO;
            
            this.CloseViewCommand = new DelegateCommand<object>(this.CloseView, this.CanCloseView);
            this.LoadEntitiesCommand = new DelegateCommand<object>(this.LoadEntities, this.CanLoadEntities);
            this.SearchCommand = new DelegateCommand<object>(this.Search, this.CanSearch);
            
           // this.LoadEntityCommand = new DelegateCommand<object>(this.LoadEntity, this.CanLoadEntity);
            //this.LoadEntityCommand = new DelegateCommand<object>(this.LoadEntity, this.CanLoadEntity);

            _dataProvider = new CRMDataProvider();

            RetrieveEntities();

        }

        
         #endregion


         #region Mathods

        private void CloseView(object commandArg)
        {
            base.CloseView();
        }
        private bool CanCloseView(object commandArg)
        {
            return true;
        }

        private bool CanLoadEntities(object commandArg)
        {
            return true;
        }

        private bool CanLoadEntity(object commandArg)
        {
            return true;
        }

        private bool CanSearch(object commandArg)
        {
            return true;
        }
     

        
        #endregion


        #region Load Entities Command

        public DelegateCommand<object> LoadEntitiesCommand { get; private set; }
        public DelegateCommand<object> LoadEntityCommand { get; private set; }
        

        private void LoadEntities(object commandArg)
        {
            RetrieveEntities();

        }

       

        private void RetrieveEntities()
        {
            IsBusy = true;

            AsyncCallback asyncCallback = (result =>
            {
                IOrganizationService service = (IOrganizationService)result.AsyncState;
                ObservableCollection<EntityMetadata> data = (ObservableCollection<EntityMetadata>)service.EndExecute(result).Results[0].Value;
                
                Action method = () =>
                {
                    var entities = from a in data
                                   orderby a.SchemaName
                                   select a;
                    
                    EntityList = entities;

                    LoadEntityList();

                    IsBusy = false;
                };

                this.View.Dispatcher.BeginInvoke(method);
            });

            this._dataProvider.RetrieveEntities(asyncCallback);
        }

        private void Search(object commandArg)
        {
            string text = Convert.ToString(commandArg);
            if (!String.IsNullOrEmpty(text))
                SearchText = text;

           LoadEntityList();
        }

        private void LoadEntityList()
        {
            IsBusy = true;
            
            Action method = () =>
            {
                int Total = 0;

                if (EntityList != null)
                {
                    var items = from a in EntityList
                                orderby a.SchemaName
                                select a;

                    if (!String.IsNullOrEmpty(SearchText))
                    {
                        items = from a in EntityList
                                where a.SchemaName.ToLower().Contains(SearchText.ToLower())
                                | a.MetadataId.Value.ToString().ToLower().Contains(SearchText.ToLower())
                                | a.LogicalName.ToLower().Contains(SearchText)
                                | a.ObjectTypeCode.ToString().Contains(SearchText)
                                orderby a.SchemaName
                                select a;
                    }

                    FilteredEntityList = items;
                    Total = FilteredEntityList.Count<EntityMetadata>();
                }

                this.HeaderInfo = string.Format("{0} ({1})", HEADER_INFO, Total);
                IsBusy = false;

            };

            this.View.Dispatcher.BeginInvoke(method);
        }
       

        #endregion

    }
}
